#include <stdio.h>
#include "dbcParse_PublicDefine.h"


/* sint类型数据为负值时，进行补码手动转换 */
static sint64 complementToOriginal(uint64 num, int end) 
{
    // uint64 mask = (1ULL<<end) - 1;
	// uint64 mask1 = ~mask;
	uint64 mask = ~((1ULL<<end) - 1);
	num = num | mask;
	num = ~(num) + 1;

	return -num;
}


// canSigConfig: 信号的配置参数
// pCanRawData: CAN报文原始数据
// pData: 解析出信号值后存放的位置
uint8 dbcParse_CanSignalDecode(const tCANSIGNALCONFIG *canSigConfig, const uint8 const *pCanRawData, void *pData)
{
#ifdef PARAMETER_CHECK
	/* 参数检查，不合理的参数直接返回ERR */
	if(	(((SIGFACTOROFFSETDATATYPE_FLOAT==canSigConfig->factorDataType)||(SIGFACTOROFFSETDATATYPE_FLOAT==canSigConfig->offsetDataType)) && (SIGPHYDATATYPE_FLOAT==canSigConfig->dataType))
		||((SIGFACTOROFFSETDATATYPE_INTPOSITIVE==canSigConfig->factorDataType) && (SIGFACTOROFFSETDATATYPE_INTPOSITIVE==canSigConfig->offsetDataType) && (SIGRAWDATATYPE_UNSIGNED==canSigConfig->rawDataType) && (canSigConfig->dataType>=SIGPHYDATATYPE_UINT8 && canSigConfig->dataType<=SIGPHYDATATYPE_UINT64))
		||((SIGFACTOROFFSETDATATYPE_INTNEGATIVE==canSigConfig->factorDataType || SIGFACTOROFFSETDATATYPE_INTNEGATIVE==canSigConfig->offsetDataType) && (SIGRAWDATATYPE_UNSIGNED==canSigConfig->rawDataType) && (canSigConfig->dataType>=SIGPHYDATATYPE_SINT8 && canSigConfig->dataType<=SIGPHYDATATYPE_SINT64))
		||((SIGFACTOROFFSETDATATYPE_FLOAT!=canSigConfig->factorDataType && SIGFACTOROFFSETDATATYPE_FLOAT!=canSigConfig->offsetDataType) && (SIGRAWDATATYPE_SIGNED==canSigConfig->rawDataType) && (canSigConfig->dataType>=SIGPHYDATATYPE_SINT8 && canSigConfig->dataType<=SIGPHYDATATYPE_SINT64))
	)
	{
		// continue
	}
	else
	{
		return RET_DATATYPE_ERR;
	}
#endif

	uint64 signalRawDataUint64 = 0u;
	sint64 signalRawDataSint64 = 0;
	
	/* 计算原始数据 */
	if(SIGBYTEENDIAN_MOTOROLAR == canSigConfig->dataEndian)
	{
		/* 摩托罗拉格式数据解析 */
		if((canSigConfig->startBit+1 - canSigConfig->lengthBits)/8 == (canSigConfig->startBit/8))
		{
			/* 信号未超过一个字节 */
			uint8 sigEndBit = 0u;	/* 信号结束bit位 */
			uint8 sigLeftBits = 0u;		/* 信号在字节中左侧剩余bit位数 */
			uint8 sigRightBits = 0u;	/* 信号在字节中右侧剩余bit位数 */
			/* 信号在同一个字节中 */
			sigEndBit = canSigConfig->startBit+1 - canSigConfig->lengthBits;
			sigLeftBits = (canSigConfig->startBit/8+1)*8-1 - canSigConfig->startBit;
			sigRightBits = sigEndBit - (canSigConfig->startBit/8)*8;
			uint8 byteIndex = canSigConfig->startBit/8;
			if(SIGRAWDATATYPE_UNSIGNED == canSigConfig->rawDataType)
			{
				signalRawDataUint64 = ( ((pCanRawData[byteIndex]<<sigLeftBits)&0x00FF) >>sigLeftBits)>>sigRightBits;
			}
			else if(SIGRAWDATATYPE_SIGNED == canSigConfig->rawDataType)
			{
				signalRawDataSint64 = ((pCanRawData[byteIndex]<<sigLeftBits)>>sigLeftBits)>>sigRightBits;
				if((pCanRawData[byteIndex]<<sigLeftBits)&0x80)	/* 负数 */
				{
					signalRawDataSint64 = complementToOriginal(signalRawDataSint64, canSigConfig->lengthBits);
				}
			}
		}
		else
		{
			/* 信号超过了一个字节 */
			uint8 startByteIndex = canSigConfig->startBit/8;		/* 起始位所在字节序号 */
			uint8 startByteBits = canSigConfig->startBit - startByteIndex*8 + 1;		/* 起始位所在字节中，信号所占据的bit位数 */
			uint8 sigLeftBitsExceptFristByte = canSigConfig->lengthBits - startByteBits;		/* 信号除去起始位所在字节所占位数的剩余位数 */
			uint8 endByteIndex = sigLeftBitsExceptFristByte/8 + 1 + startByteIndex;		/* 信号结束位所在字节序号 */
			uint8 endByteBits = sigLeftBitsExceptFristByte - (sigLeftBitsExceptFristByte/8)*8;	/* 信号在结束位所在字节中，所占据的bit位数 */
			
			if(SIGRAWDATATYPE_UNSIGNED == canSigConfig->rawDataType)
			{
				signalRawDataUint64 = ((pCanRawData[startByteIndex]<<(8-startByteBits))&0x00FF)>>(8-startByteBits);
				uint8 i = 0u;
				for(i=0u; i<endByteIndex-startByteIndex-1; i++)
				{
					signalRawDataUint64 = signalRawDataUint64<<8 | pCanRawData[startByteIndex+i+1];
				}
				uint8 signalLastByte = pCanRawData[endByteIndex]>>(8-endByteBits);
				signalRawDataUint64 = (signalRawDataUint64<<endByteBits) | signalLastByte;
			}
			else if(SIGRAWDATATYPE_SIGNED == canSigConfig->rawDataType)
			{
				signalRawDataSint64 = ((pCanRawData[startByteIndex]<<(8-startByteBits))&0x00FF)>>(8-startByteBits);
				uint8 i = 0u;
				for(i=0u; i<endByteIndex-startByteIndex-1; i++)
				{
					signalRawDataSint64 = signalRawDataSint64<<8 | pCanRawData[startByteIndex+i+1];
				}
				uint8 signalLastByte = pCanRawData[endByteIndex]>>(8-endByteBits);
				signalRawDataSint64 = (signalRawDataSint64<<endByteBits) | signalLastByte;

				if((pCanRawData[startByteIndex]<<(8-startByteBits)) & 0x80)	/* 负数 */
				{
					signalRawDataSint64 = complementToOriginal(signalRawDataSint64, canSigConfig->lengthBits);
				}
			}
		}
	}
	else if(SIGBYTEENDIAN_INTEL == canSigConfig->dataEndian)
	{
		/* 因特尔格式数据解析 */
		if((canSigConfig->startBit+canSigConfig->lengthBits-1)/8 == (canSigConfig->startBit/8))
		{
			/* 信号在同一个字节中 */
			uint8 sigEndBit = canSigConfig->startBit + canSigConfig->lengthBits - 1;	/* 信号结束bit位 */
			uint8 sigLeftBits = (canSigConfig->startBit/8+1)*8-1 - sigEndBit;	/* 信号在字节中左侧剩余bit位数 */
			uint8 sigRightBits = canSigConfig->startBit - (canSigConfig->startBit/8)*8;	/* 信号在字节中右侧剩余bit位数 */
			uint8 byteIndex = canSigConfig->startBit/8;

			if(SIGRAWDATATYPE_UNSIGNED == canSigConfig->rawDataType)
			{
				signalRawDataUint64 = ( ((pCanRawData[byteIndex]<<sigLeftBits)&0x00FF) >>sigLeftBits)>>sigRightBits;
			}
			else if(SIGRAWDATATYPE_SIGNED == canSigConfig->rawDataType)
			{
				signalRawDataSint64 = ((pCanRawData[byteIndex]<<sigLeftBits)>>sigLeftBits)>>sigRightBits;
				if(pCanRawData[byteIndex]<<sigLeftBits & 0x80)	/* 最高位如果1，则为负数 */ 
				{
					signalRawDataSint64 = complementToOriginal(signalRawDataSint64, canSigConfig->lengthBits);
				}
			}
		}
		else
		{
			/* 信号超过了一个字节 */
			uint8 startByteIndex = canSigConfig->startBit/8;		/* 起始位所在字节序号 */
			uint8 startByteBits = (canSigConfig->startBit/8 + 1)*8 - canSigConfig->startBit;	/* 起始位所在字节中，信号所占据的bit位数 */
			uint8 sigLeftBitsExceptFristByte = canSigConfig->lengthBits - startByteBits;		/* 信号除去起始位所在字节所占位数的剩余位数 */
            uint8 endByteIndex = sigLeftBitsExceptFristByte/8 + 1 + startByteIndex;		/* 信号结束位所在字节序号 */
            uint8 endByteBits = sigLeftBitsExceptFristByte - (sigLeftBitsExceptFristByte/8)*8;	/* 信号在结束位所在字节中，所占据的bit位数 */

			if(SIGRAWDATATYPE_UNSIGNED == canSigConfig->rawDataType)
			{
				signalRawDataUint64 = pCanRawData[startByteIndex]>>(8-startByteBits);		/* 处理第一个字节 */
				uint8 i = 0u;
				for(i=0u; i<endByteIndex-startByteIndex-1; i++)		/* 处理中间字节 */
				{
					signalRawDataUint64 = signalRawDataUint64 | (pCanRawData[startByteIndex+i+1]<<(8*i+startByteBits));
				}
				uint8 signalLastByte = (pCanRawData[endByteIndex]<<(8-endByteBits) & 0xFF)>>(8-endByteBits);
				signalRawDataUint64 = (signalLastByte<<(canSigConfig->lengthBits-endByteBits)) | signalRawDataUint64;
			}
			else if(SIGRAWDATATYPE_SIGNED == canSigConfig->rawDataType)
			{
				signalRawDataSint64 = pCanRawData[startByteIndex]>>(8-startByteBits);		/* 处理第一个字节 */
				uint8 i = 0u;
				for(i=0u; i<endByteIndex-startByteIndex-1; i++)		/* 处理中间字节 */
				{
					signalRawDataSint64 = signalRawDataSint64 | (pCanRawData[startByteIndex+i+1]<<(8*i+startByteBits));
				}

				uint8 signalLastByte = (pCanRawData[endByteIndex]<<(8-endByteBits) & 0xFF)>>(8-endByteBits);
				signalRawDataSint64 = (signalLastByte<<(canSigConfig->lengthBits-endByteBits)) | signalRawDataSint64;
				if(pCanRawData[endByteIndex]<<(8-endByteBits) & 0x80)	/* 负数 */
				{
					signalRawDataSint64 = complementToOriginal(signalRawDataSint64, canSigConfig->lengthBits);
				}
			}
		}
	}
	
	uint64 tempFactorValUint64 = 0u;
	sint64 tempFactorValSint64 = 0;
	double tempFactorValFloat = 0.0;
	uint64 tempOffsetValUint64 = 0u;
	sint64 tempOffsetValSint64 = 0;
	double tempOffsetValFloat = 0.0;
	uint64 tempSignalValUint64 = 0u;
	sint64 tempSignalValSint64 = 0;
	double tempSignalValFloat = 0.0;
	switch(canSigConfig->dataType)
	{
		case SIGPHYDATATYPE_FLOAT:
			/* 计算物理值 */
			if(SIGRAWDATATYPE_UNSIGNED == canSigConfig->rawDataType)
			{
				tempSignalValFloat = ((double)signalRawDataUint64)*canSigConfig->factorVal + canSigConfig->offsetVal;
			}
			else if(SIGRAWDATATYPE_SIGNED == canSigConfig->rawDataType)
			{
				tempSignalValFloat = ((double)signalRawDataSint64)*canSigConfig->factorVal + canSigConfig->offsetVal;
			}

#ifdef CANSIGNAL_PHYVAL_MAXMIN_CHECK
			/* 判断信号物理值是否超过限值 */
			if( (canSigConfig->minimumValid && (tempSignalValFloat<canSigConfig->minimum))
                || ((canSigConfig->maxminumValid) && (tempSignalValFloat>canSigConfig->maximum))  )
            {
                return RET_SIGPHYVAL_EXCEED_MAXMIN;
            }
#endif

			/* 赋值到CAN信号 */
			*((double *)pData) = tempSignalValFloat;
		break;

		case SIGPHYDATATYPE_UINT8:
		case SIGPHYDATATYPE_UINT16:
		case SIGPHYDATATYPE_UINT32:
		case SIGPHYDATATYPE_UINT64:
			tempFactorValUint64 = (uint64)canSigConfig->factorVal;
			tempOffsetValUint64 = (uint64)canSigConfig->offsetVal;
			/* 计算物理值 */
			if(SIGRAWDATATYPE_UNSIGNED == canSigConfig->rawDataType)
			{
				tempSignalValUint64 = signalRawDataUint64*tempFactorValUint64 + tempOffsetValUint64;
			}
			else if(SIGRAWDATATYPE_SIGNED == canSigConfig->rawDataType)
			{
				tempSignalValUint64 = signalRawDataSint64*tempFactorValUint64 + tempOffsetValUint64;
			}

#ifdef CANSIGNAL_PHYVAL_MAXMIN_CHECK
			/* 判断信号物理值是否超过限值 */
			if( (canSigConfig->minimumValid && (tempSignalValUint64<canSigConfig->minimum))
                || ((canSigConfig->maxminumValid) && (tempSignalValUint64>canSigConfig->maximum))  )
            {
                return RET_SIGPHYVAL_EXCEED_MAXMIN;
            }
#endif

			/* 根据信号的数据类型进行强制类型转换 */
			if(SIGPHYDATATYPE_UINT8 == canSigConfig->dataType)
			{
				*((uint8 *)pData) = (uint8)tempSignalValUint64;
			}
			else if(SIGPHYDATATYPE_UINT16 == canSigConfig->dataType)
			{
				*((uint16 *)pData) = (uint16)tempSignalValUint64;
			}
			else if(SIGPHYDATATYPE_UINT32 == canSigConfig->dataType)
			{
				*((uint32 *)pData) = (uint32)tempSignalValUint64;
			}
			else if(SIGPHYDATATYPE_UINT64 == canSigConfig->dataType)
			{
				*((uint64 *)pData) = (uint64)tempSignalValUint64;
			}
			else
			{
				return RET_DATATYPE_ERR;
			}
		break;

		case SIGPHYDATATYPE_SINT8:
		case SIGPHYDATATYPE_SINT16:
		case SIGPHYDATATYPE_SINT32:
		case SIGPHYDATATYPE_SINT64:
			tempFactorValSint64 = (sint64)canSigConfig->factorVal;
			tempOffsetValSint64 = (sint64)canSigConfig->offsetVal;
			/* 计算物理值 */
			if(SIGRAWDATATYPE_UNSIGNED == canSigConfig->rawDataType)
			{
				tempSignalValSint64 = (sint64)(signalRawDataUint64*tempFactorValSint64 + tempOffsetValSint64);
			}
			else if(SIGRAWDATATYPE_SIGNED == canSigConfig->rawDataType)
			{
				tempSignalValSint64 = (sint64)(signalRawDataSint64*tempFactorValSint64 + tempOffsetValSint64);
			}

#ifdef CANSIGNAL_PHYVAL_MAXMIN_CHECK
			/* 判断信号物理值是否超过限值 */
			if( (canSigConfig->minimumValid && (tempSignalValSint64<canSigConfig->minimum))
                || ((canSigConfig->maxminumValid) && (tempSignalValSint64>canSigConfig->maximum))  )
            {
                return RET_SIGPHYVAL_EXCEED_MAXMIN;
            }
#endif

			/* 根据信号数据类型进行强制类型转换 */
			if(SIGPHYDATATYPE_SINT8 == canSigConfig->dataType)
			{
				*((sint8 *)pData) = (sint8)tempSignalValSint64;
			}
			else if(SIGPHYDATATYPE_SINT16 == canSigConfig->dataType)
			{
				*((sint16 *)pData) = (sint16)tempSignalValSint64;
			}
			else if(SIGPHYDATATYPE_SINT32 == canSigConfig->dataType)
			{
				*((sint32 *)pData) = (sint32)tempSignalValSint64;
			}
			else if(SIGPHYDATATYPE_SINT64 == canSigConfig->dataType)
			{
				*((sint64 *)pData) = (sint64)tempSignalValSint64;
			}
			else
			{
				return RET_DATATYPE_ERR;
			}
		break;

		default:
			return RET_DATATYPE_ERR;
		break;
	}

	return RET_OK;
}
